package org.vectrics.recruiter.struts.admin;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.apache.log4j.*;
import javax.servlet.http.HttpServletRequest;

import org.vectrics.DataException;
import org.vectrics.SystemException;
import org.vectrics.common.db.SimpleCodedObject;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.history.HistoryProvider;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.recruiter.RecruitServiceLocator;
import org.vectrics.recruiter.user.CandidateInfo;
import org.vectrics.recruiter.user.Interview;
import org.vectrics.recruiter.user.InterviewResultType;
import org.vectrics.recruiter.job.Job;
import org.vectrics.recruiter.job.JobCandidate;
import org.vectrics.struts.Request;
import org.vectrics.struts.VectricsActionData;
import org.vectrics.struts.VectricsStrutsAction;
import org.vectrics.user.Person;
import org.vectrics.user.PersonEncounterStatusType;
import javax.servlet.jsp.JspException;

/**
 * This class saves the result of an interview.  The user is prompted for a result if the interview 
 * status transitions to 'completed'.
 * @author Mike Moore
 *
 */
public class SaveInterviewResultAction extends VectricsStrutsAction {
    private static Category log = Category.getInstance(SaveInterviewResultAction.class);
	public static String LOCATION_PARAM = "location";
	boolean newInterviewCreated = false;

	
	/**
	 * Save the result type and description of the interview.
	 */
	public String doExecute(VectricsActionData actionData)	throws JspException {
		Request request = actionData.getRequest();
		String forward = "success";		 	
		
		InterviewForm form = (InterviewForm)actionData.getForm(); 

		boolean cancelButtonPressed = actionData.wasButtonPressed("cancel");
        
		if (form == null) {
			log.error("form is null");
			throw new JspException("Action expected interview form to not be NULL");
		}
		else {
			log.info("Form class = " + form.getClass().getName());
		}
		
		String interviewId = form.getId();
		
		Interview interview = null;
		ThreadProperties.getSession().clear();
		interview = RecruitServiceLocator.getRecruitUserService().findInterviewById(new Long(interviewId));
		log.info("Before result select, interview=" + interview);
		
		if (log.isDebugEnabled())
			log.debug("Updating interview result: " + interview.getId());

		if (interview == null) {
			throw new JspException("Interview could not be found or created.  ID = " + interviewId);
		}
		
		if (!cancelButtonPressed) {
			log.debug("Cancel button was not pressed, saving interview result");
			try {
				log.debug("setting data for interview");
				interview.setResult(form.getResult());
				PersonEncounterStatusType statusType = interview.getStatusType();
				
				String resultTypeCode = form.getResultCode();
				InterviewResultType resultType = RecruitServiceLocator.getRecruitUserService().findInterviewResultType(resultTypeCode);
				if (resultType == null) {
					throw new SystemException("Could not find result type code: " + resultTypeCode);
				}
				
				interview.setResultType(resultType);
				
				if (log.isDebugEnabled()) {
					log.debug(" - Interview result type:    " + interview.getResultType());
					log.debug(" - Interview result desc:    " + interview.getResult());
					log.debug(" - Interview status:         " + interview.getStatusType().getName());
				}
				
				log.info("Saving result, interview=" + interview);
				RecruitServiceLocator.getRecruitUserService().updateInterview(interview);
				ThreadProperties.forcedCommit();
				
				Long jobId = new Long(form.getJobId());
				Job job = RecruitServiceLocator.getJobProvider().findJob(jobId);
				job.getJobCandidates();
				Person person = CoreServiceLocator.getPersonService().findPersonById(new Long(form.getPersonId()));
				CandidateInfo candidate = RecruitServiceLocator.getRecruitUserService().createCandidateInfoIfNotExist(person);
				RecruitServiceLocator.getRecruitUserService().updateCandidateInfo(candidate);
				
				ThreadProperties.getSession().evict(job);
				job = RecruitServiceLocator.getJobProvider().findJob(jobId);
				JobCandidate jobCandidate = job.findJobCandidate(candidate);
				request.setAttribute("jobCandidateId", jobCandidate.getId().toString());
			} catch (Exception ex) {
				log.error("Exception copying properties from interview form", ex);
				throw new JspException("Exception copying properties from interview form", ex);
			}
		} else {
			log.debug("Cancel button pressed, result not saved.");
			Long jobId = new Long(form.getJobId());
			Job job = RecruitServiceLocator.getJobProvider().findJob(jobId);
			Person person = CoreServiceLocator.getPersonService().findPersonById(new Long(form.getPersonId()));
			CandidateInfo candidate = RecruitServiceLocator.getRecruitUserService().createCandidateInfoIfNotExist(person);
			if (job != null) {
				JobCandidate jobCandidate = job.findJobCandidate(candidate);
				request.setAttribute("jobCandidateId", jobCandidate.getId().toString());
			}
			if (form.getNewInterviewCreated().trim().equalsIgnoreCase("true")) {
				try {
					RecruitServiceLocator.getRecruitUserService().removeInterview(interview);
					ThreadProperties.forcedCommit();
				}	catch (DataException de) {
					log.error("DataException while removing interview", de);
					throw new JspException("DataException while removing interview", de);
				}
			}
		}
		
		return (forward);
	}

	/**
	 * Method determines if the current status of the interview requires the user to enter a result of the interview.
	 * @param statusType
	 * @param actionData
	 * @return
	 */
	private boolean doesStatusRequireInterviewResult(PersonEncounterStatusType statusType, VectricsActionData actionData) {
		Request request = actionData.getRequest();
		Collection resultTypes = RecruitServiceLocator.getRecruitUserService().findInterviewResultTypesForStatus(statusType);
		if (resultTypes.size() > 0) {
			Collection resultTypeDescriptions = new ArrayList();
			Iterator iter = resultTypes.iterator();
			while (iter.hasNext()) {
				InterviewResultType resultType = (InterviewResultType)iter.next();
				SimpleCodedObject resultTypeWithDescription = new SimpleCodedObject();
				resultTypeWithDescription.setCode(resultType.getCode());
				resultTypeWithDescription.setName(actionData.getPhrase(resultType.getDescriptionCode()));
				resultTypeDescriptions.add(resultTypeWithDescription);
			}
			request.setAttribute("resultTypes", resultTypeDescriptions);
		}
		
		return(resultTypes.size() > 0);
	}
	
	protected void sendEvent(HttpServletRequest request, Interview interview, Person authPerson) {
		String interviewerName = "Not Given";
		if (interview.getLeadPerson() != null)
			interviewerName = interview.getLeadPerson().getName();
		
		if (newInterviewCreated) {
			HistoryProvider.getInstance().createHistory(Interview.OBJECT_TYPE, interview.getId().toString(), 
				"intrv_create", authPerson, 
					"Created a new interview with the web interface.  Candidate: " + interview.getPerson().getName() + "  Interviewer: " + interviewerName);
		} else {
			HistoryProvider.getInstance().createHistory(Job.OBJECT_TYPE, interview.getId().toString(), 
				"intrv_update", authPerson, 
				"Interview information changed with the web interface.  Candidate: " + interview.getPerson().getName() + "  Interviewer: " + interviewerName);
		}
	}
	
		
}
